package org.apache.zookeeper;

import java.util.Iterator;
import java.util.LinkedList;
import java.util.TreeMap;

/**
 * Created by IntelliJ IDEA.
 * User: wangw
 * Date: 2011-6-1
 * Time: 19:18:10
 * To change this template use File | Settings | File Templates.
 */
public class TimeoutChecker extends Thread {

    private TreeMap<Long, LinkedList<TimeoutHandler>> events = new TreeMap<Long, LinkedList<TimeoutHandler>>();

    private boolean running = true;

    public void addEvent(TimeoutHandler event) {
        synchronized (events) {
            if (!events.containsKey(event.getTimeoutTime())) {
                events.put(event.getTimeoutTime(), new LinkedList<TimeoutHandler>());
            }
            events.get(event.getTimeoutTime()).addLast(event);
        }
    }

    public void close(){
        running = false;
    }

    public void run() {
        while (running) {

            long nextTimeoutTime = -1;
            synchronized (events) {
                if(events.size() != 0)
                    nextTimeoutTime = events.firstKey();
            }
            if (nextTimeoutTime == -1) {
                try {
                    sleep(5000);
                }
                catch (InterruptedException e) {
                }
                continue;
            } else if (nextTimeoutTime > System.currentTimeMillis()) {
                try {
                    sleep(nextTimeoutTime - System.currentTimeMillis());
                }
                catch (InterruptedException e) {
                }
            }

            synchronized (events) {
                long time = events.firstKey();
                if (time > System.currentTimeMillis())
                    continue;
                LinkedList<TimeoutHandler> expiredEvents = events.remove(time);

                for (TimeoutHandler event : expiredEvents)
                    if (!event.isFinished()) {
                        event.handleTimeout();
                        if (!event.isFinished()) {
                            if (!events.containsKey(event.getTimeoutTime())) {
                                events.put(event.getTimeoutTime(), new LinkedList<TimeoutHandler>());
                            }
                            events.get(event.getTimeoutTime()).addLast(event);
                        }
                    }
            }
        }
    }
}

